package org.destinyshine.cricket.server;

import org.apache.commons.lang3.StringUtils;
import org.destinyshine.cricket.connector.Connector;
import org.destinyshine.cricket.connector.nio.SocketChannelConnector;
import org.destinyshine.cricket.connector.Connection;
import org.destinyshine.cricket.connector.ConnectionReceiver;
import org.destinyshine.cricket.container.WebApplicationContainer;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

/**
 * Created by jianyu.liu@hnlark.com on 2016/6/12.
 *
 * @author jianyu.liu@hnlark.com
 */
public class CricketServer extends AbstractLifecycle {

    private WebApplicationContainer webApplicationContainer;

    private List<Connector> connectors;

    public <T extends Connector> T createConnector(Class<T> clazz) {
        try {

            return clazz.getConstructor(ConnectionReceiver.class).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * for example: "tcp:127.0.0.1:8080"
     *
     * @param configuration for example: "tcp:127.0.0.1:8080"
     */
    public Connector createConnector(String configuration) {
        String[] config = StringUtils.split(configuration, ':');
        if (StringUtils.equals(config[0], "tcp")) {
            String host = config[1];
            int port = Integer.parseInt(config[2]);
            SocketChannelConnector connector = new SocketChannelConnector(new ConnectionReceiverWrapper(), host, port);
            return connector;
        } else {
            throw new UnsupportedOperationException();
        }
    }

    @Override
    protected void initInternal() throws LifecycleException {

    }

    @Override
    protected void startInternal() throws LifecycleException {
        setState(LifecycleState.STARTING);
        webApplicationContainer.start();
    }

    @Override
    protected void stopInternal() throws LifecycleException {

    }

    @Override
    protected void destroyInternal() throws LifecycleException {

    }

    public WebApplicationContainer getWebApplicationContainer() {
        return webApplicationContainer;
    }

    public void setWebApplicationContainer(WebApplicationContainer webApplicationContainer) {
        this.webApplicationContainer = webApplicationContainer;
    }

    protected class ConnectionReceiverWrapper implements ConnectionReceiver {

        @Override
        public void recevieConnection(Connection connection) {
            webApplicationContainer.recevieConnection(connection);
        }
    }
}
